package ghelp

// InArray 判断元素是否在数组中
func InArray[T comparable](item T, items []T) bool {
	for _, v := range items {
		if v == item {
			return true
		}
	}
	return false
}

// GenTree 将数组map生成tree
// items 将要排序的数组
// addEmptyChild child为空时是否返回空数组，默认true
// option[0] id别名，默认id
// option[1] pid别名，默认pid
// option[2] child别名，默认返回child
// example:
//
//	 items := []map[string]interface{}{
//		   {"id": "1", "name": "1"},
//		   {"id": "2", "pid": "1", "name": "2"},
//		   {"id": "3", "pid": "1", "name": "3"},
//		   {"id": "4", "pid": "2", "name": "3"},
//	  }
//
// JsonEncode(GenTree(items, true))
func GenTree(items []map[string]interface{}, addEmptyChild bool, option ...string) []map[string]interface{} {
	// 赋默认值
	_option := []string{"id", "pid", "child"}
	if len(option) > 0 {
		for k, v := range option {
			_option[k] = v
		}
	}

	newData := make(map[interface{}]map[string]interface{})
	var mapSort []interface{}
	for k, v := range items {
		if addEmptyChild {
			items[k][_option[2]] = []interface{}{}
		}
		newData[v[_option[0]]] = v
		mapSort = append(mapSort, v[_option[0]])
	}

	var tree []map[string]interface{}
	for _, k := range mapSort {
		v := newData[k]
		_, find := v[_option[1]]
		var b bool
		if find {
			if _, ok := newData[v[_option[1]]]; ok {
				b = true
			}
		}
		if b {
			newData[v[_option[1]]][_option[2]] = append(newData[v[_option[1]]][_option[2]].([]interface{}), newData[v[_option[0]]])
		} else {
			tree = append(tree, newData[v[_option[0]]])
		}
	}
	return tree
}

// ArrayKeys 获取map里面所有键名
func ArrayKeys(items map[interface{}]interface{}) interface{} {
	i, keys := 0, make([]interface{}, len(items))
	for key := range items {
		keys[i] = key
		i++
	}
	return keys
}

// ArrayUnique 去除数组中重复的值
func ArrayUnique[T comparable](arr []T) []T {
	m := make(map[T]bool)
	for _, v := range arr {
		m[v] = true
	}
	var newArr []T
	for k := range m {
		newArr = append(newArr, k)
	}
	return newArr
}

// CompareArray 比较两个数组，返回新增和删除的元素
func CompareArray[T comparable](arr1 []T, arr2 []T) ([]T, []T) {
	mArr1 := make(map[T]bool)
	mArr2 := make(map[T]bool)
	for _, v := range arr1 {
		mArr1[v] = true
	}
	for _, v := range arr2 {
		mArr2[v] = true
	}
	var addArr, delArr []T
	for k := range mArr1 {
		if _, ok := mArr2[k]; !ok {
			delArr = append(delArr, k)
		}
	}
	for k := range mArr2 {
		if _, ok := mArr1[k]; !ok {
			addArr = append(addArr, k)
		}
	}
	return addArr, delArr
}
